#ifndef FOUNDATION_DISCOVERY_CLIENT_IMPL_H
#define FOUNDATION_DISCOVERY_CLIENT_IMPL_H

#include "discovery_client.h"
#include "utils_noncopyable.h"
#include "utils_log.h"
#include "utils_callback_list.h"
#include <uv.h>
#include <string>
#include <thread>
#include <atomic>
#include <functional>
#include <vector>
#include <map>
#include <mutex>
#include "protocol.h"

namespace El {
namespace Discovery {

class DiscoveryClientImpl : public IDiscoveryClient, public NoCopyable {

public:
    DiscoveryClientImpl();
    ~DiscoveryClientImpl();

    bool Start(int32_t timeout = 5) override;
    void Stop() override;

    int32_t Register(const Proc &proc) override;
    void Unregister(int32_t handle) override;

private:
    // 静态回调函数
    static void OnAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf);
    static void OnUdpRecv(uv_udp_t *handle,
                          ssize_t nread,
                          const uv_buf_t *buf,
                          const struct sockaddr *addr,
                          unsigned flags);
    static void OnUdpSend(uv_udp_send_t *req, int status);
    static void WalkCallback(uv_handle_t *handle, void *arg);

    // 成员回调函数
    void HandleUdpRecv(ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags);
    void SendDiscoveryRequest();

    // 辅助方法
    void RunLoop();
    void StopLoopHandles();

    // HTTP辅助方法
    bool ParseHttpMessage(const std::string &raw_data, std::string &headers, std::string &body);
    std::string BuildHttpRequest(const std::string &method, const std::string &body);

private:
    // libuv循环和句柄
    uv_loop_t *loop_ = nullptr;
    uv_udp_t udpHandle_{};
    std::thread loopThread_;
    std::atomic<bool> running_{false};
    Protocol::IProtocolPtr protocol_;

    // 回调函数管理
    Utils::CallbackList<void, const nlohmann::json &> callbacks_;

    // 发现超时
    int32_t timeoutSeconds_ = 5;

    // 多播配置
    static const char *MULTICAST_ADDR;
    static const int PORT;
    struct sockaddr_in sendAddr_{};
};

} // namespace Discovery
} // namespace El

#endif // FOUNDATION_DISCOVERY_CLIENT_IMPL_H
